package com.py.custom.tms.application.jvm.bytecode;

public class InterpretBytecode {
    /*
    前置知识

    class文件结构
        u4				magic
        u2				minor_version
        u2				major_version
        u2				constant_pool_count
        cp_info			constant_pool
        u2				access_flags
        u2				this_class
        u2				super_class
        u2				interfaces_count
        u2				interfaces
        u2				fields_count
        field_info		fields
        u2				methods_count
        method_info		methods
        u2				attributes_count
        attribute_info	attributes


    类型：field_info
        struct field_info {
            类型             名称
            u2              access_flags,
            u2              name_index,
            u2              descriptor_index,
            u2              attribute_count,
            attribute_info  attributes
        }

    类型：method_info
        struct method_info {
            类型             名称
            u2              access_flags,
            u2              name_index,
            u2              descriptor_index,
            u2              attribute_count,
            attribute_info  attributes
        }
    类型：attribute_info
        struct attribute_info {
            类型     名称
            u2      attribute_name_index,
            u4      attribute_length,
            u1      info
        }

    类型：Code
        struct Code {
            类型             名称
            （ u2              attribute_name_index,
            u4              attribute_length,）把上面的综合写一起了，可以不用看，继续向下解析
            u2              max_stack,
            u2              max_locals,
            u4              code_length,
            u1              code,  数量 code_length
            u2              exception_length,
            exception_info  exception_table,  数量 exception_length
            u2              attributes_count,
            attribute_info  attributes 数量 attributes_count
        }

    类型：LineNumberTable
        struct line_number_table {
            类型                    名称
            u2                      line_number_table_length,
            line_number_info        line_number_info 数量 line_number_table_length
        }

    类型：line_number_info
        struct line_number_info {
            类型    名称
            u2     start_pc,
            u2     line_number
        }

    类型：LocalVariableTable
        struct local_variable_table {
            类型                    名称
            u2                      local_variable_table_length,
            local_variable_info     line_number_table 数量 local_variable_table_length
        }

    类型：local_variable_info
        struct local_variable_info {
            类型     名称
            u2      start_pc;
            u2      length;
            u2      name_index;
            u2      descriptor_index;
            u2      index;
        }


    类型：cp_info
        1.CONSTANT_Utf8_info (tag-u1, length-u2, bytes)
            类型标志为1，UTF-8编码的字符串。tag表示标志，用1字节表示，当值为1的时候说明是该类型，
            length表示字符串占用字节的数量，用2个字节表示。bytes表示字符串。
        2.CONSTANT_Integer_info (tag-u1, bytes-u4)
            类型标志为3，整型字面量。tag表示标志，用1字节表示，当值为3的时候说明是该类型，
            bytes表示存储的int的值。
        3.CONSTANT_Float_info (tag-u1, bytes-u4)
            类型标志为4，浮点型字面量。tag表示标志，用1字节表示，当值为4的时候说明是该类型，
            bytes表示存储的float的值。
        4.CONSTANT_Long_info (tag-u1, bytes-u8)
            类型标志为5，长整型字面量。tag表示标志，用1字节表示，当值为5的时候说明是该类型，
            bytes表示存储的Long的值。
        5.CONSTANT_Double_info (tag-u1, bytes-u8)
            类型标志为6，双精度字面量。tag表示标志，用1字节表示，当值为6的时候说明是该类型，
            bytes表示存储的Double的值。
        6.CONSTANT_Class_info (tag-u1, index-u2)
            类型标志为7，类或接口类型的字面量。tag表示标志，用1字节表示，当值为7的时候说明是该类型，
            index表示常量池数组中的索引。
        7.CONSTANT_String_info (tag-u1, index-u2)
            类型标志为8，字符串类型的字面量。tag表示标志，用1字节表示，当值为8的时候说明是该类型，
            index表示常量池数组中的索引，指向字符串字面量的索引。
        8.CONSTANT_Fieldref_info (tag-u1, index-u2, index-u2)
            类型标志为9，字段的符号引用。tag表示标志，用1字节表示，当值为9的时候说明是该类型，
            第一个index表示常量池数组中的索引，指向声明字段的类或接口描述符CONSTANT_Class_info的索引项。
            第二个index标志常量池数组中的索引，指向字段描述符CONSTANT_NameAndType的索引项。
        9.CONSTANT_Methodref_info (tag-u1, index-u2, index-u2)
            类型标志为10，类中方法的符号引用。tag表示标志，用1字节表示，当值为10的时候说明是该类型，
            第一个index表示常量池数组中的索引，指向声明方法的类或接口描述符CONSTANT_Class_info的索引项。
            第二个index标志常量池数组中的索引，指向字段描述符CONSTANT_NameAndType的索引项。
        10.CONSTANT_InterfaceMethodref_info (tag-u1, index-u2, index-u2)
            类型标志为11，接口中方法的符号引用。tag表示标志，用1字节表示，当值为11的时候说明是该类型，
            第一个index表示常量池数组中的索引，指向声明方法的接口描述符CONSTANT_Class_info的索引项。
            第二个index标志常量池数组中的索引，指向字段描述符CONSTANT_NameAndType的索引项。
        11.CONSTANT_NameAndType (tag-u1, index-u2, index-u2)
            类型标志为12，字段或方法的部分符号引用。tag表示标志，用1字节表示，当值为12的时候说明是该类型，
            第一个index表示常量池数组中的索引，指向该字段或方法名称常量项的索引。
            第二个index标志常量池数组中的索引，指向该字段或方法描述符常量项的索引。
        12.CONSTANT_MethodHandle_info (tag-u1, reference_kind-u1, reference_index-u2)
            类型标志为15，方法句柄。tag表示标志，用1字节表示，当值为15的时候说明是该类型，
            reference_kind值必须在1～9之间，它决定类方法句柄的类型。方法句柄的值表示方法句柄的字节行为。
            reference_index值必须是对常量池的有效索引。
        13.CONSTANT_MethodType_info (tag-u1, descriptor_index-u2)
            类型标志为16，表示方法类型。tag表示标志，用1字节表示，当值为16的时候说明是该类型，
            descriptor_index值必须是对常量池的有效索引，常量池在该索引处的项必须是CONTANT_Utf8_info结构，表示方法的描述符。
        14.CONSTANT_InvokeDynamic_info (tag-u1, bootstrap_method_attr_index-u2, name_and_type_index-u2)
            类型标志为18，表示一个动态调用点。tag表示标志，用1字节表示，当值为18的时候说明是该类型，
     */


    /*
        字节
        CA FE BA BE 00 00 00 34 00 18 0A 00 04 00 14 09
        00 03 00 15 07 00 16 07 00 17 01 00 01 61 01 00
        01 49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29
        56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E
        75 6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63
        61 6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01
        00 04 74 68 69 73 01 00 34 4C 63 6F 6D 2F 70 79
        2F 63 75 73 74 6F 6D 2F 74 6D 73 2F 61 70 70 6C
        69 63 61 74 69 6F 6E 2F 6A 76 6D 2F 62 79 74 65
        63 6F 64 65 2F 4D 79 54 65 73 74 31 3B 01 00 04
        67 65 74 41 01 00 03 28 29 49 01 00 04 73 65 74
        41 01 00 04 28 49 29 56 01 00 0A 53 6F 75 72 63
        65 46 69 6C 65 01 00 0C 4D 79 54 65 73 74 31 2E
        6A 61 76 61 0C 00 07 00 08 0C 00 05 00 06 01 00
        32 63 6F 6D 2F 70 79 2F 63 75 73 74 6F 6D 2F 74
        6D 73 2F 61 70 70 6C 69 63 61 74 69 6F 6E 2F 6A
        76 6D 2F 62 79 74 65 63 6F 64 65 2F 4D 79 54 65
        73 74 31 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F
        4F 62 6A 65 63 74 00 21 00 03 00 04 00 00 00 01
        00 02 00 05 00 06 00 00 00 03 00 01 00 07 00 08
        00 01 00 09 00 00 00 38 00 02 00 01 00 00 00 0A
        2A B7 00 01 2A 04 B5 00 02 Bl 00 00 00 02 00 0A
        00 00 00 0A 00 02 00 00 00 03 00 04 00 05 00 0B
        00 00 00 0C 00 01 00 00 00 0A 00 0C 00 0D 00 00
        00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01
        00 01 00 00 00 05 2A B4 00 02 AC 00 00 00 02 00
        0A 00 00 00 06 00 01 00 00 00 08 00 0B 00 00 00
        0C 00 01 00 00 00 05 00 0C 00 0D 00 00  00 01 00
        10 00 11 00 01 00 09 00 00 00 3E 00 02 00 02 00
        00 00 06 2A IB B5 00 02 Bl 00 00 00 02 00 0A 00
        00 00 0A 00 02 00 00 00 0C 00 05 00 0D 00 0B 00
        00 00 16 00 02 00 00 00 06 00 0C 00 0D 00 00 00
        00 00 06 00 05 00 06 00 01 00 01 00 12 00 00 00
        02 00 13
     */

    /*
        CA EF BA BE	：4字节u4，魔数
        00 00 ：2字节u2，表示次版本号；0
        00 34 ：2字节u2，表示主版本号，十进制数字 52；1.8
        00 18 ：2字节u2，表示常量池数组中元素个数，十进制 24；(24-1)个常量，0位置用于表示null

        //表示访问标志，用来区分是什么类型的常量，现在常量池数组中的元素类型有14种。

        索引：1
        0A ：1字节u1，tag=10 ，CONSTANT_Methodref_info
        00 04 ：4 表示CONSTANT_Class_info类型的索引位置。
        00 14 ：20 表示CONSTANT_NameAndType类型的索引位置。

        索引：2
        09 ：1字节u1，tag=9 ，CONSTANT_Fieldref_info
        00 03 ：4 表示CONSTANT_Class_info类型的索引位置。
        00 15 ：21 表示CONSTANT_NameAndType类型的索引位置。

        索引：3
        07 ：tag=7 ，CONSTANT_Class_info
        00 16 ：22 表示CONSTANT_Class_info类型的索引位置。

        索引：4
        07 ：tag=7 ，CONSTANT_Class_info
        00 17 : 22 表示CONSTANT_Class_info类型的索引位置。

        索引：5
        01 ：tag=1 ，CONSTANT_Utf8_info
        00 01 ：1 表示1个字节。
        61 ：ascii 码，表示 a

        索引：6
        01 ：tag=1 ，CONSTANT_Utf8_info
        00 01 ：1 表示1个字节。
        49 ：utf8编码，表示 I

        索引：7
        01 ：tag=1 ，CONSTANT_Utf8_info
        00 06 ：6 表示6个字节。
        3C 69 6E 69 74 3E ：utf8编码，<init>

        索引：8
        01 ：tag=1 ，CONSTANT_Utf8_info
        00 03 ：3 表示3个字节。
        28 29 56 ：utf8编码，()V

        索引：9
        01 ：tag=1 ，CONSTANT_Utf8_info
        00 04 ：4 表示4个字节。
        43 6F 64 65 ：utf8编码，Code

        索引：10
        01 ：tag=1 ，CONSTANT_Utf8_info
        00 0F ：15 表示15个字节。
        4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 ：utf8编码，LineNumberTable

        索引：11
        01 ：tag=1 ，CONSTANT_Utf8_info
        00 12 ：15 表示15个字节。
        4C 6F 63 61 6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 ：utf8编码，LocalVariableTable

        索引：12
        01 ：tag=1 ，CONSTANT_Utf8_info
        00 04 ：4 表示4个字节。
        74 68 69 73 ：utf8编码，this

        索引：13
        01 ：tag=1 ，CONSTANT_Utf8_info
        00 34 ：3*16+4 表示52个字节。
        4C 63 6F 6D 2F 70 79
        2F 63 75 73 74 6F 6D 2F 74 6D 73 2F 61 70 70 6C
        69 63 61 74 69 6F 6E 2F 6A 76 6D 2F 62 79 74 65
        63 6F 64 65 2F 4D 79 54 65 73 74 31 3B ：utf8编码，Lcom/py/custom/tms/application/jvm/bytecode/MyTest1;

        索引：14
        01 ：tag=1 ，CONSTANT_Utf8_info
        00 04 ：4 表示4个字节。
        67 65 74 41 ：utf8编码，getA

        索引：15
        01 ：tag=1 ，CONSTANT_Utf8_info
        00 03 ：3 表示3个字节。
        28 29 49 ：utf8编码，()I

        索引：16
        01 ：tag=1 ，CONSTANT_Utf8_info
        00 04 ：4 表示4个字节。
        73 65 74 41 ：utf8编码，setA

        索引：17
        01 ：tag=1 ，CONSTANT_Utf8_info
        00 04 ：4 表示4个字节。
        28 49 29 56 ：utf8编码，(I)V

        索引：18
        01 ：tag=1 ，CONSTANT_Utf8_info
        00 0A ：10 表示10个字节。
        53 6F 75 72 63 65 46 69 6C 65 ：utf8编码，SourceFile

        索引：19
        01 ：tag=1 ，CONSTANT_Utf8_info
        00 0C ：12 表示12个字节。
        4D 79 54 65 73 74 31 2E 6A 61 76 61 ：utf8编码，MyTest1.java

        索引：20
        0C ：tag=12 ，CONSTANT_NameAndType
        00 07 ：7 ，表示字段或方法名称 常量池中的索引。
        00 08 ：8 ，字段或方法描述符  常量池中的索引。

        索引：21
        0C ：tag=12 ，CONSTANT_NameAndType
        00 05 ：5 ，表示字段或方法名称 常量池中的索引。
        00 06 ：6 ，字段或方法描述符  常量池中的索引。

        索引：22
        01 ：tag=1 ，CONSTANT_Utf8_info
        00 32 ：3*16+2 表示50个字节。
        63 6F 6D 2F 70 79 2F 63 75 73 74 6F 6D 2F 74
        6D 73 2F 61 70 70 6C 69 63 61 74 69 6F 6E 2F 6A
        76 6D 2F 62 79 74 65 63 6F 64 65 2F 4D 79 54 65
        73 74 31 ：utf8编码，com/py/custom/tms/application/jvm/bytecode/MyTest1

        索引：23
        01 ：tag=1 ，CONSTANT_Utf8_info
        00 10 ：16 表示16个字节。
        6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 ：utf8编码，com/py/custom/tms/application/jvm/bytecode/MyTest1

        属性名称：access_flags
        00 21 ：表示 public

        属性名称：this_class
        00 03 ：3 表示指向常量池中的索引

        属性名称：super_class
        00 04 ：4 表示指向常量池中的索引

        属性名称：interfaces_count
        00 00 ：0 表示接口数量

        属性名称：interfaces
        没有

        属性名称：fields_count
        00 01 ：1 表示类里面属性数量

        属性名称：fields
        struct field_info {
            类型             名称
            u2              access_flags,
            u2              name_index,
            u2              descriptor_index,
            u2              attribute_count,
            attribute_info  attributes
        }
        00 02 ：表示private
        00 05 ：5 表示变量名称对应的 常量池中的索引位置的值
        00 06 ：6 表示描述符对应的 常量池中的索引位置的值
        00 00 ：0 表示属性的数量。

        属性名称：fields_count
        00 03 ：3 表示类里面方法的数量

        属性名称：methods
        struct method_info {
            类型             名称
            u2              access_flags,
            u2              name_index,
            u2              descriptor_index,
            u2              attribute_count,
            attribute_info  attributes
        }
        属性名称：access_flags
        00 01 ：表示public

        属性名称：name_index
        00 07 ：7 表示方法名称对应的 常量池中的索引位置的值

        属性名称：descriptor_index
        00 08 ：8 表示描述符对应的 常量池中的索引位置的值

        属性名称：attribute_count
        00 01 ：表示属性的数量。

        属性名称：attributes
        struct attribute_info {
            类型     名称
            u2      attribute_name_index,
            u4      attribute_length,
            u1      info // 注意，说明info只有一个，字节长度是 attribute_length 其对应的类型使用Code进行分析。
        }
        00 09 ：9 表示名称对应的 常量池中的索引位置的值
        00 00 00 38 ：3*16+8 表示 56 个字节长度
        分析code
        00 02 ：2 表示max_stack
        00 01 ：1 表示局部变量表
        00 00 00 0A ：10 ，指令的长度。code_length
        2A B7 00 01 2A 04 B5 00 02 Bl ：cpu执行的指令，字节码，一个字节的解析；
                例子，2A 表示aload_0意思是(Load reference from local variable); 加载引用从局部变量表索引0处；aload_1表示从1处。
                字节码：
                0 aload_0
                1 invokespecial #1 <java/lang/Object.<init> : ()V>
                4 aload_0
                5 iconst_1
                6 putfield #2 <com/py/custom/tms/application/jvm/bytecode/MyTest1.a : I>
                9 return
        00 00 ：0 异常表的数量为0
        00 02 ：2 表示属性数量。attribute_info

        00 0A ：attribute_name_index；LineNumberTable：类型
        00 00 00 0A ：attribute_length
        00 02 ：2 表示 line_number_info的数量
        00 00 00 03 ：0 表示start_pc程序代码的pc计数器位置，3表示源代码位置
        00 04 00 05 ：4 表示start_pc程序代码的pc计数器位置，5表示源代码位置

        00 0B ：attribute_name_index；LocalVariableTable：类型
        00 00 00 0C：attribute_length；12
        00 01 ：1 表示 local_variable_table_length 的数量
        00 00 ：0 表示 start_pc
        00 0A ：10 表示 length
        00 0C ：12 表示 name_index 指向常量池的索引处的值。
        00 0D ：13 表示局部变量表的类型 descriptor_index 指向常量池的索引处的值。
        00 00 ：0 表示局部变量slot槽位置 index


        00 01 ：表示访问标志 public
        00 0E ：14 表示方法的名称指向的 常量池的索引 值
        00 0F ：15 表示方法的描述符指向的 常量池的索引 值
        00 01 ：表示属性的数量。
            00 09 ：9 ，attribute_name_index表示属性名称对应的常量池的索引
            00 00 00 2F ：2*16+15=47 attribute_length 表示info所占用字节数
            00 01 ：1 表示最大的栈深度 max_stack
            00 01 ：1 表示局部变量表的大小，max_locals
            00 00 00 05 ：表示code的长度，5个字节
            2A B4 00 02 AC ：对应的指令是下面的解释。
            00 00 ：表示异常的长度，0字节
            00 02 ：属性数量，2个；
            00 0A ：attribute_name_index；LineNumberTable：类型，表示行号表
            00 00 00 06 ：attribute_length；表示LineNumberTable类型 数据长度为 6字节
            00 01 ：line_number_table_length；表示行号表的个数；line_number_info类型
            00 00 00 08 ：起始pc：0000表示0；对应代码的行号0008：第8行。

            00 0B ：attribute_name_index；LocalVariableTable：类型，表示局部变量表
            00 00 00 0C ：attribute_length；占用字节数，12字节
            00 01 ：表示 local_variable_table的数量为1个
            00 00 ：start_pc；起始pc地址为0
            00 05 ：长度是5
            00 0C ：name_index
            00 0D ：descriptor_index
            00 00 ：index，表的索引，为0存放this
            ：
            0 aload_0
            1 getfield #2 <com/py/custom/tms/application/jvm/bytecode/MyTest1.a : I>
            4 ireturn

            00 01 ：access_flags；表示方法的访问标志。
            00 10 ：name_index；表示方法名称的索引。
            00 11 ：descriptor_index；方法描述符的索引
            00 01 ：attribute_count属性的数量1
            00 09 ：attribute_name_index；类型名字的索引表示Code
            00 00 00 3E ：attribute_length；表示占用的字节数，3*16+14
            00 02 ：
            00 02 ：
            00 00 00 06 ：code_length
            2A IB B5 00 02 Bl ：
            00 00 ：exception_length
            00 02 ：attributes_count
            00 0A ：attribute_name_index：LineNumberTable
            00 00 00 0A ：attribute_length
            00 02 ：line_number_table_length数量2
            00 00 00 0C ：start_pc，line_number
            00 05 00 0D ：start_pc，line_number

            00 0B ：attribute_name_index：LocalVariableTable
            00 00 00 16 ：attribute_length：1*16+6
            00 02 ：local_variable_table_length；2个数量，local_variable_info
            00 00 ：start_pc
            00 06 ：length
            00 0C ：name_index
            00 0D ：descriptor_index
            00 00 ：index

            00 00 00 06 00 05 00 06 00 01 ：start_pc、length、name_index、descriptor_index、index

            00 01 ：attributes_count 1个
            00 12 ：attribute_name_index；1*16+2：SourceFile
            00 00 00 02 ：attribute_length 2长度
            00 13 ：1*16+3：对应常量池的索引，MyTest1.java

     */

}
